#include "client.h"

extern int userid;

void putsHandler(int sockfd, train_t* t){
    Msg m;

    int filefd = open(t->buff, O_RDWR);
    if(filefd < 0){
        printf("file %s is not exist.\n", t->buff);
        return ;
    }
    sendn(sockfd, t, 4 + 4 + t->len);
   
    //获取文件的长度
    struct stat fileInfo;
    memset(&fileInfo, 0, sizeof(fileInfo));
    fstat(filefd, &fileInfo);
    int length = fileInfo.st_size;
    printf("file length: %d\n", length);

    //获取文件的MD5码的16进制字符串(原来是16位unsigned char)
    char md5_hash[33];
    getMD5(filefd, length, md5_hash);
    
    //发送userid
    sendn(sockfd, &userid, sizeof(userid));

    //发送MD5码
    sendn(sockfd, md5_hash, strlen(md5_hash));

    //发送文件长度
    sendn(sockfd, &length, sizeof(length));

    //接收是否可以文件秒传的消息
    getMsg(sockfd, &m);

    //只能正常发送
    if(m.type == MSG_TYPE_TRANSFER_NORMAL){

        //发送文件内容
        if(length > 100*1024*1024){//大于100M,使用mmap
            char * p_map = mmap(NULL, length, 
                                PROT_READ|PROT_WRITE, MAP_SHARED, filefd, 0);
            sendn(sockfd, p_map, length);
            munmap(p_map, length);
        }else{//使用小火车
            int donesize = 0;
            while(1) {
                train_t2 t2;
                memset(&t2, 0, sizeof(t2));//清空缓冲区
                int ret = read(filefd, t2.buff, sizeof(t2.buff));
                if(ret == 0) {//文件读到了末尾
                    break;
                }
                t2.len = ret;
                //发送文件内容
                ret = sendn(sockfd, &t2, 4 + t2.len);
                if(ret == -1) {
                    break;
                }
                donesize += (ret-4);
                printf("The file is recv: %5.2f%%\r", 100.00*donesize/length);
                fflush(stdout);
            }
            printf("\n");
        }
    }

    //接收最终结果
    getMsg(sockfd, &m);
    printf("%s\n", m.data);
} 
